package thread;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * @author Mr.Sun
 * @date 2022年03月09日 22:01
 */
public class Memoizer4<A, V> implements Computable<A, V> {
    private final Map<A, Future<V>> cache = new ConcurrentHashMap<>();
    private final Computable<A, V> c;

    public Memoizer4(Computable<A, V> c) {
        this.c = c;
    }

    @Override
    public V compute(A arg) throws InterruptedException {
        while (true) {
            Future<V> future = cache.get(arg);
            if (future == null) {
                FutureTask<V> task = new FutureTask<>(() -> c.compute(arg));
                future = task;
                cache.putIfAbsent(arg, task);
                // 这里将调用c.compute(arg)
                task.run();
            }
            try {
                return future.get();
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
